package semant.first_pass;

import semant.Env;
import symbol.Symbol;
import symbol.ClassInfo;
import symbol.MethodInfo;
import symbol.VarInfo;
import syntaxtree.Formal;
import syntaxtree.VisitorAdapter;

final class FormalHandler extends VisitorAdapter {

    private Env env;
    private ClassInfo cinfo;
    private MethodInfo minfo;

    private FormalHandler(Env e, ClassInfo c, MethodInfo m){
	super();
	env = e;
	cinfo = c;
	minfo = m;
    }

    static void firstPass(Env e, ClassInfo c, MethodInfo m, Formal f){
	FormalHandler h = new FormalHandler(e, c, m);
	f.accept(h);
    }

    public void visit(Formal node){
	// insere parametro no metodo
    	Symbol name = Symbol.symbol(node.name.s);
    	VarInfo v = new VarInfo(node.type, name);

    	if(!minfo.addFormal(v)){

	    VarInfo old = minfo.formalsTable.get(name);
	    if(old == null)
		minfo.localsTable.get(name);
	    if(old == null)
		throw new Error();

	    env.err.Error(node.type, new Object[]{"Variavel \'" + name + "\' redeclarada para metodo '" + minfo.name + "'", "Declaracao anterior aqui: [" + old.type.line + "," + old.type.row + "]"});
    	}
    }

}
